package com.example.springrabbitmq.config;

import com.example.springrabbitmq.constant.Constants;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Configuration
public class RabbitMQConfig {
    // 简单模式
    @Bean("simpleQueue")
    public Queue simpleQueue() {
        return QueueBuilder.durable(Constants.SIMPLE_QUEUE).build();
    }

    // 工作队列模式
    @Bean("workQueue")
    public Queue workQueue() {
        return QueueBuilder.durable(Constants.WORK_QUEUE).build();
    }

    // 发布订阅模式
    @Bean("fanoutQueue1")
    public Queue fanoutQueue1() {
        return QueueBuilder.durable(Constants.PUBLISH_QUEUE_1).build();
    }

    @Bean("fanoutQueue2")
    public Queue fanoutQueue2() {
        return QueueBuilder.durable(Constants.PUBLISH_QUEUE_2).build();
    }

    // 声明交换机
    @Bean("fanoutExchange")
    public FanoutExchange fanoutExchange() {
        return ExchangeBuilder.fanoutExchange(Constants.PUBLISH_CHANGE).durable(true).build();
    }

    // 绑定交换机和队列
    @Bean("fanoutQueueBinding1")
    public Binding fanoutQueueBinding1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,@Qualifier("fanoutQueue1") Queue queue) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    @Bean("fanoutQueueBinding2")
    public Binding fanoutQueueBinding2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    // 路由模式
    @Bean("routingQueue1")
    public Queue routingQueue1() {
        return QueueBuilder.durable(Constants.ROUTINT_QUEUE_1).build();
    }

    @Bean("routingQueue2")
    public Queue routingQueue2() {
        return QueueBuilder.durable(Constants.ROUTINT_QUEUE_2).build();
    }

    // 声明交换机
    @Bean("routingExchange")
    public DirectExchange routingExchange() {
        return ExchangeBuilder.directExchange(Constants.ROUTING_CHANGE).durable(true).build();
    }

    // 绑定交换机和队列
    @Bean("routingQueueBinding1")
    public Binding routingQueueBinding1(@Qualifier("routingExchange") DirectExchange directExchange, @Qualifier("routingQueue1") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("a");
    }

    @Bean("routingQueueBinding2")
    public Binding routingQueueBinding2(@Qualifier("routingExchange") DirectExchange directExchange, @Qualifier("routingQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("a");
    }

    @Bean("routingQueueBinding3")
    public Binding routingQueueBinding3(@Qualifier("routingExchange") DirectExchange directExchange, @Qualifier("routingQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("b");
    }

    @Bean("routingQueueBinding4")
    public Binding routingQueueBinding4(@Qualifier("routingExchange") DirectExchange directExchange, @Qualifier("routingQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("c");
    }

    // 通配符模式
    @Bean("topicsQueue1")
    public Queue topicsQueue1() {
        return QueueBuilder.nonDurable(Constants.TOPICS_QUEUE_1).build();
    }
    @Bean("topicsQueue2")
    public Queue topicsQueue2() {
        return QueueBuilder.durable(Constants.TOPICS_QUEUE_2).build();
    }
    @Bean("topicsExchange")
    public TopicExchange topicExchange() {
        return ExchangeBuilder.topicExchange(Constants.TOPICS_CHANGE).durable(true).build();
    }

    // 绑定交换机和队列
    @Bean("topicsQueueBinding1")
    public Binding topicsQueueBinding1(@Qualifier("topicsExchange") TopicExchange topicExchange, @Qualifier("topicsQueue1") Queue queue) {
        return BindingBuilder.bind(queue).to(topicExchange).with("*.*.a");
    }

    @Bean("topicsQueueBinding2")
    public Binding topicsQueueBinding2(@Qualifier("topicsExchange") TopicExchange topicExchange, @Qualifier("topicsQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(topicExchange).with("*.b.*");
    }
    @Bean("topicsQueueBinding3")
    public Binding topicsQueueBinding3(@Qualifier("topicsExchange") TopicExchange topicExchange, @Qualifier("topicsQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(topicExchange).with("c.#");
    }

    // 消息确认
    @Bean("ackQueue")
    public Queue ackQueue() {
        return QueueBuilder.durable(Constants.ACK_QUEUE).build();
    }
    @Bean("ackExchange")
    public DirectExchange ackExchange() {
        return ExchangeBuilder.directExchange(Constants.ACK_EXCHANGE).build();
    }
    // 绑定交换机和队列
    @Bean("ackQueueBinding")
    public Binding ackQueueBinding(@Qualifier("ackExchange") DirectExchange ackExchange, @Qualifier("ackQueue") Queue ackQueue) {
        return BindingBuilder.bind(ackQueue).to(ackExchange).with("ack");
    }

    // confirm 模式
    @Bean("confirmQueue")
    public Queue confrimQueue() {
        return QueueBuilder.durable(Constants.CONFIRM_QUEUE).build();
    }
    @Bean("confirmExchange")
    public DirectExchange confirmExchange() {
        return ExchangeBuilder.directExchange(Constants.CONFIRM_EXCHANGE).build();
    }

    @Bean("confirmBinding")
    public Binding confirmBinding(@Qualifier("confirmExchange") Exchange confirmExchange,@Qualifier("confirmQueue") Queue confrimQueue) {
        return BindingBuilder.bind(confrimQueue).to(confirmExchange).with("confirm").noargs();
    }

    // 持久化
    @Bean("persistenceQueue")
    public Queue persistenceQueue() {
        return QueueBuilder.durable(Constants.PERSISTENCE_QUEUE).build();
    }
    @Bean("persistenceExchange")
    public DirectExchange persistenceExchange() {
        return ExchangeBuilder.directExchange(Constants.PERSISTENCE_EXCHANGE).durable(true).build();
    }

    @Bean("presBinding")
    public Binding persistenceBinding(@Qualifier("persistenceExchange") Exchange persistenceExchange,@Qualifier("persistenceQueue") Queue persistenceQueue) {
        return BindingBuilder.bind(persistenceQueue).to(persistenceExchange).with("persistence").noargs();
    }

    // 重试
    @Bean("retryQueue")
    public Queue retryQueue() {
        return QueueBuilder.durable(Constants.RETRY_QUEUE).build();
    }
    @Bean("retryExchange")
    public DirectExchange retryExchange() {
        return ExchangeBuilder.directExchange(Constants.RETRY_EXCHANGE).durable(true).build();
    }
    @Bean("retryBinding")
    public Binding retryBinding(@Qualifier("retryExchange") Exchange retryExchange,@Qualifier("retryQueue") Queue retryQueue) {
        return BindingBuilder.bind(retryQueue).to(retryExchange).with("retry").noargs();
    }

    // ttl
    @Bean("ttlQueue")
    public Queue ttlQueue() {
        Map<String, Object> arguments = new HashMap<>();
        // 设置过期时间为 20 s
        arguments.put("x-message-ttl", 20000);
        return QueueBuilder.durable(Constants.TTL_QUEUE).withArguments(arguments).build();
    }

    @Bean("ttlQueue2")
    public Queue ttlQueue2() {
        // 队列中消息过期时间为 20s
        return QueueBuilder.durable(Constants.TTL_QUEUE_2).build();
    }

    @Bean("ttlExchange")
    public DirectExchange ttlExchange() {
        return ExchangeBuilder.directExchange(Constants.TTL_EXCHANGE).durable(true).build();
    }
    @Bean("ttlBinding")
    public Binding ttlBinding(@Qualifier("ttlExchange") Exchange ttlExchange,@Qualifier("ttlQueue") Queue ttlQueue) {
        return BindingBuilder.bind(ttlQueue).to(ttlExchange).with("ttl").noargs();
    }

    @Bean("ttlBinding2")
    public Binding ttlBinding2(@Qualifier("ttlExchange") Exchange ttlExchange,@Qualifier("ttlQueue2") Queue ttlQueue2) {
        return BindingBuilder.bind(ttlQueue2).to(ttlExchange).with("ttl").noargs();
    }
}
